package com.xlh.service.system.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xlh.dao.system.OperationExtendMapper;
import com.xlh.dao.system.OperationMapper;
import com.xlh.dao.system.ext.OperationMapperExt;
import com.xlh.dto.PageDTO;
import com.xlh.dto.course.ChapterBasicInfoDTO;
import com.xlh.dto.course.CourseBasicDTO;
import com.xlh.dto.system.IpRegionDataDTO;
import com.xlh.dto.system.OperationDTO;
import com.xlh.dto.system.OperationUserDTO;
import com.xlh.enums.course.ChapterResourceViewEnum;
import com.xlh.enums.user.EventCodeEnum;
import com.xlh.enums.user.IdentityEnum;
import com.xlh.enums.user.RoleEnum;
import com.xlh.enums.user.UserStatusEnum;
import com.xlh.exception.common.BadRequestException;
import com.xlh.exception.common.NotFoundException;
import com.xlh.pojo.system.Operation;
import com.xlh.pojo.system.OperationExample;
import com.xlh.pojo.system.OperationExtend;
import com.xlh.pojo.system.OperationExtendExample;
import com.xlh.security.UserInfoHolder;
import com.xlh.service.course.ChapterService;
import com.xlh.service.course.CourseService;
import com.xlh.service.system.OperationService;
import com.xlh.util.BeanUtil;
import com.xlh.util.ExcelsUtil;
import com.xlh.util.RequestUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 日志
 * <p>
 * Created by lx on 2019/1/28.
 */
@Service
public class OperationServiceImpl implements OperationService {

    @Autowired
    private OperationMapper operationMapper;

    @Autowired
    private OperationMapperExt operationMapperExt;

    @Autowired
    private OperationExtendMapper operationExtendMapper;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Autowired
    private CourseService courseService;

    public List<Operation> listOperation(Long userId, List<Long> objIds, EventCodeEnum eventCodeEnum) {
        OperationExample example = new OperationExample();
        example.setOrderByClause("id DESC");
        OperationExample.Criteria cri = example.createCriteria();
        if (userId != null) {
            cri.andUserIdEqualTo(userId);
        }
        if (CollectionUtils.isNotEmpty(objIds)) {
            cri.andObjIdIn(objIds);
        }
        if (eventCodeEnum != null) {
            cri.andEventCodeEqualTo(eventCodeEnum.getCode());
        }
        return operationMapper.selectByExample(example);
    }

    @Override
    public List<Operation> listOperation(List<Long> userIds, List<Long> objIds, EventCodeEnum eventCodeEnum) {
        OperationExample example = new OperationExample();
        OperationExample.Criteria cri = example.createCriteria();
        if (CollectionUtils.isNotEmpty(userIds)) {
            cri.andUserIdIn(userIds);
        }
        if (CollectionUtils.isNotEmpty(objIds)) {
            cri.andObjIdIn(objIds);
        }
        if (eventCodeEnum != null) {
            cri.andEventCodeEqualTo(eventCodeEnum.getCode());
        }
        return operationMapper.selectByExample(example);
    }

    @Override
    public List<Long> queryOperationIds(Long userId, List<Long> objIds, EventCodeEnum eventCodeEnum) {
        List<Operation> operations = listOperation(userId, objIds, eventCodeEnum);
        if (CollectionUtils.isEmpty(operations)) return null;
        return operations.stream().map(Operation::getObjId).distinct().collect(Collectors.toList());
    }

    @Override
    public PageDTO<OperationUserDTO> listOperationByPage(
            Integer pageNum, Integer pageSize, String userInfo, String roleName,
            String schoolName, String startTime, String endTime, List<EventCodeEnum> eventCodeEnums) {

        // 获取角色 并 设置角色
        List<Integer> roles = getRoles(roleName);

        // 获取查询的事件
        List<String> codes = getEventCodes(eventCodeEnums);

        PageHelper.startPage(pageNum, pageSize);
        List<OperationUserDTO> operationUserDTOS = operationMapperExt.listOperation(
                userInfo, codes, roles, schoolName, startTime, endTime);
        PageInfo<OperationUserDTO> pageInfo = new PageInfo<>(operationUserDTOS);
        pageInfo.setList(convertPageOperationUserDTO(pageInfo.getList()));
        return new PageDTO<>(pageInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteOperation(List<Long> operationIds) {

        // 验证参数
        if (CollectionUtils.isEmpty(operationIds)) {
            throw new BadRequestException("参数不能为空错误");
        }

        // 删除流水及流水额外表数据
        OperationExample example = new OperationExample();
        example.createCriteria().andIdIn(operationIds);
        deleteOperationAndExtend(example);
    }

    private void deleteOperationAndExtend(OperationExample example) {
        List<Operation> operations = operationMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(operations)) {
            throw new BadRequestException("没有可删除的数据");
        }
        operationMapper.deleteByExample(example);
        List<Long> extendIds = operations.stream()
                .filter(operation -> operation.getOperationExtendId() != null)
                .map(Operation::getOperationExtendId).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(extendIds)) {
            deleteOperationExtend(extendIds);
        }
    }

    private void deleteOperationExtend(List<Long> extendIds) {
        OperationExtendExample example = new OperationExtendExample();
        example.createCriteria().andIdIn(extendIds);
        operationExtendMapper.deleteByExample(example);
    }

    @Override
    public void batchDeleteOperation(List<Long> objIds, List<Long> userIds, EventCodeEnum eventCodeEnum) {

        if (CollectionUtils.isEmpty(objIds) || eventCodeEnum == null) return;

        // 删除流水及流水额外表数据
        OperationExample example = new OperationExample();
        OperationExample.Criteria criteria = example.createCriteria();
        if (CollectionUtils.isNotEmpty(objIds)) {
            criteria.andObjIdIn(objIds);
        }
        if (CollectionUtils.isNotEmpty(userIds)) {
            criteria.andUserIdIn(userIds);
        }
        if (eventCodeEnum != null) {
            criteria.andEventCodeEqualTo(eventCodeEnum.getCode());
        }
        try {
            deleteOperationAndExtend(example);
        } catch (BadRequestException e) {

        }

    }

    @Override
    public OperationDTO getChapterRecording(Long userId, Long courseId) {
        // 获取用户的学习记录（倒序）
        List<Operation> operations = listOperation(userId, null, EventCodeEnum.CHAPTER_RECORDING);
        if (CollectionUtils.isEmpty(operations)) throw new NotFoundException("暂无学习记录");

        // 根据学习记录中的章节id集合，获取章节信息
        List<Long> chapterIds = operations.stream().map(Operation::getObjId).distinct().collect(Collectors.toList());
        List<ChapterBasicInfoDTO> chapterBasics = chapterService.listChapterInfo(
                Lists.newArrayList(courseId), chapterIds, null);
        if (CollectionUtils.isEmpty(chapterBasics)) throw new NotFoundException("暂无学习记录");

        // 将章节信息转换为Map<章节id, List<章节基本信息>>
        Map<Long, ChapterBasicInfoDTO> chapterIdMap = BeanUtil.mapByKey("id", chapterBasics);

        // 遍历学习记录，获取章节信息
        for (Operation operation : operations) {
            Long chapterId = operation.getObjId();
            ChapterBasicInfoDTO chapterBasic = chapterIdMap.get(chapterId);
            if (chapterIdMap.keySet().contains(chapterId) && chapterBasic != null) {
                return new OperationDTO(operation.getObjId(), chapterBasic.getName(), operation.getRemark());
            }
        }

        return null;

    }

    @Override
    public boolean updateOperationExtend(Long operationExtendId) {
        OperationExtend extend = operationExtendMapper.selectByPrimaryKey(operationExtendId);
        if (extend == null || StringUtils.isBlank(extend.getIp())) return true;

        OperationExtendExample extendExample = new OperationExtendExample();
        extendExample.createCriteria().andIpEqualTo(extend.getIp()).andCityIsNotNull();
        List<OperationExtend> operationExtends = operationExtendMapper.selectByExample(extendExample);

        if (CollectionUtils.isNotEmpty(operationExtends)) {
            extend = operationExtends.get(0);
        } else {
            try {
                IpRegionDataDTO ipRegionDataDTO = RequestUtil.getRegionInfo(extend.getIp());
                if (ipRegionDataDTO == null) return false;
                extend = BeanUtil.transform(OperationExtend.class, ipRegionDataDTO);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        extend.setId(operationExtendId);
        extend.setCreateTime(null);
        operationExtendMapper.updateByPrimaryKeySelective(extend);

        return true;
    }

    @Override
    public void exportExcel(String userInfo, String roleName, String schoolName, String startTime, String endTime,
                            List<EventCodeEnum> eventCodeEnums) {

        // 获取角色 并 设置角色
        List<Integer> roles = getRoles(roleName);

        // 获取查询的事件
        List<String> codes = getEventCodes(eventCodeEnums);

        // 从数据库中获取数据并转换
        List<OperationUserDTO> xlsData = operationMapperExt.listOperation(userInfo, codes, roles, schoolName,
                startTime, endTime);
        xlsData = convertPageOperationUserDTO(xlsData);

        // 创建excel数据
        List<List<Map<String, Object>>> list = createExcelRecord(xlsData);

        // 设置excel一些参数并下载
        List<String[]> columnNames = new ArrayList<String[]>() {
            {
                add(new String[]{"用户姓名", "工号/学号", "角色", "省份", "登陆省份", "学校", "请求名称", "请求日期", "申请人",
                        "截止日期", "状态"});
                add(new String[]{"学校", "申请人", "登陆次数"});
                add(new String[]{"课程名称", "工号/学号", "姓名", "访问次数"});
                add(new String[]{"课程名称", "课程访问次数"});
                add(new String[]{"课程名称", "章节名称", "章节访问次数"});
            }
        };
        List<String[]> keys = new ArrayList<String[]>() {
            {
                add(new String[]{"name", "userNumber", "roleName", "province", "region", "schoolName", "eventDesc",
                        "operationCreateTime", "applicant", "destroyTime", "statusName"});
                add(new String[]{"schoolName", "applicant", "loginCount"});
                add(new String[]{"courseName", "userNumber", "name", "courseRequestCount"});
                add(new String[]{"courseName", "courseRequestCount"});
                add(new String[]{"courseName", "chapterName", "chapterRequestCount"});
            }
        };
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        ExcelsUtil.ExcelOutputStream(list, keys, columnNames, "流水导出", request, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Operation insertOpertion(String ip, EventCodeEnum eventCodeEnum, Long objId) {

        // 若ip信息传递过来，则插入额外表信息
        OperationExtend extend = null;
        if (eventCodeEnum == EventCodeEnum.LOGIN) {
            extend = new OperationExtend();
            extend.setIp(ip);
            operationExtendMapper.insertSelective(extend);
        }

        // 整合流水对象并插入数据库
        Operation operation = new Operation();
        operation.setUserId(userInfoHolder.getUserId());
        operation.setRole(userInfoHolder.getUser().getRole());
        operation.setEventCode(eventCodeEnum.getCode());
        operation.setEventDesc(eventCodeEnum.getMessage());
        if (objId != null) {
            operation.setObjId(objId);
        }
        if (extend != null) {
            operation.setOperationExtendId(extend.getId());
        }
        operationMapper.insertSelective(operation);
        return operation;
    }

    @Override
    public void insertBatch(List<Operation> operations) {
        operationMapperExt.insertBatch(operations);
    }

    private List<OperationUserDTO> convertPageOperationUserDTO(List<OperationUserDTO> data) {
        data.forEach(operationUserDTO -> {
            RoleEnum roleEnum = RoleEnum.getByCode(operationUserDTO.getRole());
            if (roleEnum != null) {
                operationUserDTO.setRoleName(roleEnum.getRoleName());
            }
            UserStatusEnum statusEnum = UserStatusEnum.getByCode(operationUserDTO.getStatus());
            if (statusEnum == UserStatusEnum.DELETED) {
                operationUserDTO.setStatusName(statusEnum.getMessage());
            } else if (statusEnum == UserStatusEnum.ACCOUNT_CANCELLATION) {
                operationUserDTO.setStatusName("已销户");
            } else if (operationUserDTO.getRegion() == null
                    || !StringUtils.containsAny(operationUserDTO.getProvince(), operationUserDTO.getRegion())) {
                operationUserDTO.setStatusName("异常");
                operationUserDTO.setShowAccountCancellation(true);
            }
        });
        return data;
    }

    private List<List<Map<String, Object>>> createExcelRecord(List<OperationUserDTO> xlsData) {

        List<List<Map<String, Object>>> resultMap = Lists.newArrayList();

        // 设置流水记录
        List<Map<String, Object>> listMap = Lists.newArrayList();
        Map<String, Object> map = Maps.newHashMap();
        map.put("sheetName", "流水记录");
        listMap.add(map);
        listMap.addAll(convertOperation(xlsData));
        resultMap.add(listMap);

        // 设置学校统计记录
        List<Map<String, Object>> schoolStatisticsListMap = Lists.newArrayList();
        Map<String, Object> schoolMap = Maps.newHashMap();
        schoolMap.put("sheetName", "学校统计记录");
        schoolStatisticsListMap.add(schoolMap);
        schoolStatisticsListMap.addAll(convertSchoolStatistics(xlsData));
        resultMap.add(schoolStatisticsListMap);

        // 将数据进行转换
        List<OperationUserDTO> courseChapterOperations = covertOperationForCourseChapter(xlsData);

        // 设置课程用户统计记录
        List<Map<String, Object>> courseUserStatisticsListMap = Lists.newArrayList();
        Map<String, Object> courseUserMap = Maps.newHashMap();
        courseUserMap.put("sheetName", "课程用户统计记录");
        courseUserStatisticsListMap.add(courseUserMap);
        courseUserStatisticsListMap.addAll(convertCourseUserStatistics(courseChapterOperations));
        resultMap.add(courseUserStatisticsListMap);

        // 设置课程统计记录
        List<Map<String, Object>> courseStatisticsListMap = Lists.newArrayList();
        Map<String, Object> courseMap = Maps.newHashMap();
        courseMap.put("sheetName", "课程统计记录");
        courseStatisticsListMap.add(courseMap);
        courseStatisticsListMap.addAll(convertCourseStatistics(courseChapterOperations));
        resultMap.add(courseStatisticsListMap);

        // 设置章节统计记录
        List<Map<String, Object>> chapterStatisticsListMap = Lists.newArrayList();
        Map<String, Object> chapterMap = Maps.newHashMap();
        chapterMap.put("sheetName", "章节统计记录");
        chapterStatisticsListMap.add(chapterMap);
        chapterStatisticsListMap.addAll(convertChapterStatistics(courseChapterOperations));
        resultMap.add(chapterStatisticsListMap);

        return resultMap;
    }

    private List<Map<String, Object>> convertOperation(List<OperationUserDTO> xlsData) {
        List<Map<String, Object>> listMap = Lists.newArrayList();
        xlsData.forEach(operationUserDTO -> {
            Map<String, Object> mapValue = Maps.newHashMap();
            mapValue.put("name", operationUserDTO.getName());
            mapValue.put("userNumber", operationUserDTO.getUserNumber());
            mapValue.put("roleName", operationUserDTO.getRoleName());
            mapValue.put("province", operationUserDTO.getProvince());
            mapValue.put("region", operationUserDTO.getRegion());
            mapValue.put("schoolName", operationUserDTO.getSchoolName());
            mapValue.put("eventDesc", operationUserDTO.getEventDesc());
            mapValue.put("operationCreateTime",
                    DateUtil.format(operationUserDTO.getOperationCreateTime(), DatePattern.NORM_DATETIME_FORMAT));
            mapValue.put("applicant", operationUserDTO.getApplicant());
            /*mapValue.put("createTime",
                    DateUtil.format(operationUserDTO.getCreateTime(), DatePattern.NORM_DATETIME_FORMAT));*/
            mapValue.put("destroyTime",
                    DateUtil.format(operationUserDTO.getDestroyTime(), DatePattern.NORM_DATETIME_FORMAT));
            mapValue.put("statusName", operationUserDTO.getStatusName());
            listMap.add(mapValue);
        });
        return listMap;
    }

    private List<Map<String, Object>> convertSchoolStatistics(List<OperationUserDTO> xlsData) {
        List<Map<String, Object>> listMap = Lists.newArrayList();
        if (CollectionUtils.isEmpty(xlsData)) return listMap;

        Map<String, Map<String, Long>> schoolStatisticsMap = xlsData.stream()
                .filter(operationDTO -> Objects.equals(EventCodeEnum.LOGIN.getCode(), operationDTO.getEventCode()))
                .map(operationUserDTO -> {
                    if (StringUtils.isBlank(operationUserDTO.getSchoolName())) {
                        operationUserDTO.setSchoolName("");
                    }
                    if (StringUtils.isBlank(operationUserDTO.getApplicant())) {
                        operationUserDTO.setApplicant("");
                    }
                    return operationUserDTO;
                }).collect(Collectors.groupingBy(
                        OperationUserDTO::getSchoolName,
                        Collectors.groupingBy(OperationUserDTO::getApplicant, Collectors.counting()))
                );
        schoolStatisticsMap.forEach((schoolName, dataMap) ->
                dataMap.forEach((applicant, count) -> {
                    Map<String, Object> mapValue = Maps.newHashMap();
                    mapValue.put("schoolName", schoolName);
                    mapValue.put("applicant", applicant);
                    mapValue.put("loginCount", count);
                    listMap.add(mapValue);
                })
        );
        return listMap;
    }

    private List<OperationUserDTO> covertOperationForCourseChapter(List<OperationUserDTO> xlsData) {
        List<OperationUserDTO> chapterOperations = xlsData.stream()
                .filter(operation -> Objects.equals(EventCodeEnum.CHAPTER_RECORDING.getCode(), operation.getEventCode())
                        && (Objects.equals(ChapterResourceViewEnum.THEORY.getCode(), Integer.valueOf(operation.getRemark()))
                        || Objects.equals(ChapterResourceViewEnum.EXPERIMENT.getCode(), Integer.valueOf(operation.getRemark()))))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(chapterOperations)) return null;

        // 获取章节信息
        List<Long> chapterIds = chapterOperations.stream()
                .map(OperationUserDTO::getObjId).distinct().collect(Collectors.toList());
        List<ChapterBasicInfoDTO> chapters = chapterService.listChapter(
                null, chapterIds, null, null);
        if (CollectionUtils.isEmpty(chapters)) return null;

        List<Long> parentIds = chapters.stream()
                .filter(chapterInfo -> chapterInfo.getParentId() != null && chapterInfo.getParentId() > 0)
                .map(ChapterBasicInfoDTO::getParentId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(parentIds)) {
            chapters.addAll(chapterService.listChapter(null, parentIds, null, null));
        }

        // 获取课程信息
        List<Long> courseIds = chapters.stream()
                .map(ChapterBasicInfoDTO::getCourseId).distinct().collect(Collectors.toList());
        List<CourseBasicDTO> courses = courseService.listCourse(courseIds,
                null, null, null, null, null);
        if (CollectionUtils.isEmpty(courses)) return null;

        Map<Long, ChapterBasicInfoDTO> chapterInfoMap = BeanUtil.mapByKey("id", chapters);
        Map<Long, CourseBasicDTO> courseInfoMap = BeanUtil.mapByKey("id", courses);

        return chapterOperations.stream()
                .map(operationUserDTO -> {
                    ChapterBasicInfoDTO chapterInfo = chapterInfoMap.get(operationUserDTO.getObjId());
                    if (chapterInfo != null && chapterInfo.getParentId() != null && chapterInfo.getParentId() > 0) {
                        chapterInfo = chapterInfoMap.get(chapterInfo.getParentId());
                    }
                    if (chapterInfo != null) {
                        operationUserDTO.setChapterName(chapterInfo.getName());
                        CourseBasicDTO courseInfo = courseInfoMap.get(chapterInfo.getCourseId());
                        if (courseInfo != null) {
                            operationUserDTO.setCourseName(courseInfo.getName());
                        }
                    }
                    return operationUserDTO;
                }).collect(Collectors.toList());
    }

    private List<Map<String, Object>> convertCourseUserStatistics(List<OperationUserDTO> xlsData) {
        List<Map<String, Object>> listMap = Lists.newArrayList();
        if (CollectionUtils.isEmpty(xlsData)) return listMap;

        Map<String, OperationUserDTO> userMap = BeanUtil.mapByKey("userNumber", xlsData);
        Map<String, Map<String, Long>> courseUserStatisticsMap = xlsData.stream().collect(Collectors.groupingBy(
                OperationUserDTO::getCourseName,
                Collectors.groupingBy(OperationUserDTO::getUserNumber, Collectors.counting()))
        );
        courseUserStatisticsMap.forEach((courseName, dataMap) -> {
            dataMap.forEach((userNumber, count) -> {
                Map<String, Object> mapValue = Maps.newHashMap();
                mapValue.put("courseName", courseName);
                mapValue.put("userNumber", userNumber);
                OperationUserDTO operationUserDTO = userMap.get(userNumber);
                mapValue.put("name", operationUserDTO == null ? "" : operationUserDTO.getName());
                mapValue.put("courseRequestCount", count);
                listMap.add(mapValue);
            });
        });
        return listMap;
    }

    private List<Map<String, Object>> convertCourseStatistics(List<OperationUserDTO> xlsData) {
        List<Map<String, Object>> listMap = Lists.newArrayList();
        if (CollectionUtils.isEmpty(xlsData)) return listMap;

        Map<String, Long> courseMap = xlsData.stream()
                .collect(Collectors.groupingBy(OperationUserDTO::getCourseName, Collectors.counting()));
        courseMap.forEach((courseName, count) -> {
            Map<String, Object> mapValue = Maps.newHashMap();
            mapValue.put("courseName", courseName);
            mapValue.put("courseRequestCount", count);
            listMap.add(mapValue);
        });
        return listMap;
    }

    private List<Map<String, Object>> convertChapterStatistics(List<OperationUserDTO> xlsData) {
        List<Map<String, Object>> listMap = Lists.newArrayList();
        if (CollectionUtils.isEmpty(xlsData)) return listMap;

        Map<String, Map<String, Long>> chapterStatisticsMap = xlsData.stream().collect(Collectors.groupingBy(
                OperationUserDTO::getCourseName,
                Collectors.groupingBy(OperationUserDTO::getChapterName, Collectors.counting()))
        );
        chapterStatisticsMap.forEach((courseName, dataMap) -> {
            dataMap.forEach((chapterName, count) -> {
                Map<String, Object> mapValue = Maps.newHashMap();
                mapValue.put("courseName", courseName);
                mapValue.put("chapterName", chapterName);
                mapValue.put("chapterRequestCount", count);
                listMap.add(mapValue);
            });
        });
        return listMap;
    }

    private List<Integer> getRoles(String roleName) {
        RoleEnum roleEnum = RoleEnum.getByName(roleName);
        List<Integer> roles = roleEnum == null ? Lists.newArrayList() : Lists.newArrayList(roleEnum.getRoleCode());
        if (roleEnum == null) {
            roles.addAll(IdentityEnum.TEACHER.getRoles());
            roles.addAll(IdentityEnum.STUDENT.getRoles());
        }
        return roles;
    }

    private List<String> getEventCodes(List<EventCodeEnum> eventCodeEnums) {
        List<String> codes = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(eventCodeEnums)) {
            eventCodeEnums.forEach(eventCodeEnum -> {
                codes.add(eventCodeEnum.getCode());
            });
        }
        return codes;
    }

}
